import { AxiosProgressEvent, AxiosRequestConfig } from "axios";
import { IAxiosRequestConfig, RequestMethods } from "./types";
import { Base } from "./base";
export class Http extends Base {
  private static http: Http;
  private timer = null;
  private debPath = null;
  static of() {
    if (!Http.http) {
      Http.http = new Http();
    }
    return Http.http;
  }
  /** 通用请求工具函数 */
  public request<T>(
    method: RequestMethods,
    url: string,
    param?: IAxiosRequestConfig
  ): Promise<T> {
    // 单独处理自定义请求/响应回调
    return new Promise((resolve, reject) => {
      this.client
        .request({
          method,
          url,
          ...(param || {})
        })
        .then((response: undefined) => {
          resolve(response);
        })
        .catch(error => {
          reject(error);
        });
    });
  }

  /** 单独抽离的post工具函数 */
  public post<T = unknown, P = unknown>(
    url: string,
    data?: T,
    params?: AxiosRequestConfig<T>
  ): Promise<P> {
    return this.request<P>("post", url, { data, ...params });
  }

  /** 单独抽离的patch工具函数 */
  public patch<T = unknown, P = unknown>(
    url: string,
    data: T,
    params?: AxiosRequestConfig<T>
  ): Promise<P> {
    return this.request<P>("patch", url, { data, ...params });
  }

  /** 单独抽离的get工具函数 */
  public get<P = unknown>(
    url: string,
    params?: Record<string, unknown>,
    config?: AxiosRequestConfig
  ): Promise<P> {
    return this.request<P>("get", url, { params, ...config });
  }

  public delete<P = unknown>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<P> {
    return this.request<P>("delete", url, config);
  }

  public formData<P = unknown>(
    file: Blob | Blob[],
    path: string,
    onUploadProgress: (progressEvent: AxiosProgressEvent) => void,
    noRetry = true,
    dir?: string
  ) {
    const files = Array.isArray(file) ? file : [file];
    const formdata = new FormData();
    files.forEach(f => {
      formdata.append("file", f);
    });
    formdata.append("dir", dir);
    return this.request<P>("post", path, {
      data: formdata,
      noRetry,
      headers: { "Content-Type": "multipart/form-data" },
      onUploadProgress
    });
  }

  /**
   * 节流查询
   */
  public debVaildGet(
    url: string,
    params?: Record<string, unknown>,
    config?: AxiosRequestConfig & { delay?: number }
  ) {
    this.debPath = url;
    return new Promise(resolve => {
      if (this.timer) {
        resolve(false);
      } else {
        this.timer = setTimeout(async () => {
          const res = await this.get(this.debPath, params, config);
          resolve(res);
          if (this.timer) {
            clearTimeout(this.timer);
            this.timer = null;
          }
        }, config?.delay || 50);
      }
    });
  }
}
